﻿using MvvmCross.Core.ViewModels;
using Sidvall.FileSystemManager.Data;
using Sidvall.FileSystemManager.UI.Entities;
using Sidvall.Serialization;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Sidvall.FileSystemManager.UI.ViewModels
{
    public partial class SearchConfigViewModel
    {
        #region Public Members

        #region SearchPatterns

        private PathNameCollection _SearchPatterns;
        public PathNameCollection SearchPatterns
        {
            get
            {
                PathNameCollection items;

                if (_SearchPatterns == null)
                {
                    items = new PathNameCollection();
                    items.Add(1, CodeManager.SearchPatterns);
                    items.Add(2, CodeManager.SearchPatternsCodeFiles);
                    items.Add(3, CodeManager.SearchPatternsProjects);
                    _SearchPatterns = items;
                }
                return _SearchPatterns;
            }
        }

        #endregion
        #region Result

        private string _Result;
        public string Result
        {
            get
            {
                return _Result;
            }
            set
            {
                _Result = value;
                RaisePropertyChanged("Result");
            }
        }

        #endregion
        #region Files

        private IEnumerable<IPathName> _Files;
        public IEnumerable<IPathName> Files
        {
            get
            {
                return _Files;
            }
            private set
            {
                _Files = value;
                RaisePropertyChanged("Files");
            }
        }

        #endregion
        #region ActiveFile

        private IPathName _ActiveFile;
        public IPathName ActiveFile
        {
            get
            {
                return _ActiveFile;
            }
            set
            {
                _ActiveFile = value;
                RaisePropertyChanged("ActiveFile");
            }
        }

        #endregion

        //Commands
        #region SearchCommand

        public ICommand SearchCommand
        {
            get
            {
                return new MvxCommand(async () => await SearchAsync());
            }
        }

        #endregion
        #region SearchAsync

        public async Task SearchAsync()
        {
            Task task = null;
            if (this.ActiveEntity == null)
                return;
            using (var m = new Sidvall.Data.BusyManager(this))
            {
                try
                {
                    await Task.Run((System.Func<Task>)Search);

                    this.Files = this.SearchFiles;
                    if (!string.IsNullOrWhiteSpace(this.ActiveEntity.FolderPath))
                    {
                        SystemContext.Current.UserConfiguration.SearchConfigContext = this.ActiveEntity.Serialize();
                        await SystemContext.Current.SaveUserConfigurationAsync(SystemContext.Current.UserConfiguration);
                    }
                    this.Result = this.SearchResult;
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Unexpected Error", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion
        #region ShowFileCommand

        public ICommand ShowFileCommand
        {
            get
            {
                return new MvxCommand(async () => await ShowFileAsync());
            }
        }

        #endregion
        #region ShowFileAsync

        public async Task ShowFileAsync()
        {
            string content;
            Task task = null;

            if (this.ActiveFile == null)
                return;
            using (var m = new Sidvall.Data.BusyManager(this))
            {
                try
                {
                    if (this.ActiveFile.IsFolder)
                    {
                        await Sidvall.SystemContext.Current.LauncherManager.LaunchFileAsync(this.ActiveFile.FullName);
                    }
                    else
                    {
                        content = await Sidvall.FileSystemManager.CodeManager.GetFileContentAsync(this.ActiveFile.FullName, this.ActiveEntity.SearchPatterns,
                            this.ActiveEntity.CaseSensitive);
                        await Sidvall.UI.SystemContext.Current.DialogManager.ShowMessageAsync("File", content, Sidvall.UI.Dialogs.MessageType.Information);
                    }
                }
                catch (System.Exception ex)
                {
                    task = Sidvall.UI.SystemContext.Current.DialogManager.ShowErrorMessageAsync("Open Failed", ex);
                }
                if (task != null)
                    await task;
            }
        }

        #endregion

        #region LoadItemAsync

        protected override Task<SearchConfig> LoadItemAsync()
        {
            SearchConfig item;

            item = SearchConfig.Deserialize(SystemContext.Current.UserConfiguration.SearchConfigContext);

            return Task.FromResult(item);
        }

        #endregion
        #region OnViewEventAsync

        protected override Task OnViewEventAsync(Sidvall.UI.Views.ViewEventArgs args)
        {
            return Task.FromResult(true);
        }

        #endregion

        #region StartAsync

        protected override async Task StartAsync()
        {
            SystemContext.Current.UserConfiguration.StartPageId = Data.PageType.Search;
            await SystemContext.Current.SaveUserConfigurationAsync(SystemContext.Current.UserConfiguration);
            await DoLoadAsync();
        }

        #endregion

        #endregion
        #region Private Members

        private IEnumerable<IPathName> SearchFiles { get; set; }
        private string SearchResult { get; set; }
        #region Search

        private async Task Search()
        {
            string[] searchPatterns;

            if (!string.IsNullOrWhiteSpace(this.ActiveEntity.FileSearchPatterns))
                searchPatterns = this.ActiveEntity.FileSearchPatterns.Split(CodeManager.SearchPatternSeparator);
            else
                searchPatterns = null;
            var result = await Sidvall.FileSystemManager.CodeManager.SearchAsync(this.ActiveEntity.FolderPath, searchPatterns, this.ActiveEntity.SearchPatterns,
                this.ActiveEntity.CaseSensitive, this.ActiveEntity.SearchFolderName, this.ActiveEntity.SearchFileName, this.ActiveEntity.SearchFileContent, this.ActiveEntity.LoadDetails);
            this.SearchFiles = result.PathNames.Items;
            this.SearchResult = result.GetDescription();
        }

        #endregion

        #endregion
    }
}
